package com.binguo.socket.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.binguo.common.exception.ServiceException;
import com.binguo.common.util.ImageBase64Util;
import com.binguo.helper.ImgHelper;
import com.binguo.model.api.vo.DeskExtendVO;
import com.binguo.model.mapper.CashierDeskMapper;
import com.binguo.model.mapper.FaceMapper;
import com.binguo.model.model.*;
import com.binguo.model.repository.*;
import com.binguo.service.CustomerService;
import com.binguo.service.DeskService;
import com.binguo.socket.SocketService;
import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.naming.CompositeName;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import static com.binguo.common.exception.ErrorCode.CUSTOMER_NOT_EXIST;

/**
 * @author yuritian
 * @Title: SocketService
 * @ProjectName binguoDevelop
 * @Description: TODO
 * @date 2020-02-1814:46
 */
@Service
public class MenJinSocketService {

    private static Logger logger = LoggerFactory.getLogger(MenJinSocketService.class);


    @Autowired
    SocketService socketService;

    @Autowired
    CashierDeskRepository cashierDeskRepository;

    @Autowired
    ShopMenjinOrderRepository shopMenjinOrderRepository;

    @Autowired
    CustomerService customerService;

    @Autowired
    FaceRepository faceRepository;

    @Resource
    FaceMapper faceMapper;

    @Autowired
    CashierDeskExtendRepository cashierDeskExtendRepository;

    @Autowired
    MenjinSocketLogRepository menjinSocketLogRepository;

    @Resource
    CashierDeskMapper cashierDeskMapper;

    @Autowired
    CustomerExtendRepository customerExtendRepository;

    @Autowired
    MenjinSocketCustomerLogRepository menjinSocketCustomerLogRepository;

    @Autowired
    MenjinBindingRepository menjinBindingRepository;

    @Autowired
    CustomerGroupRepository customerGroupRepository;

    @Autowired
    DeskService deskService;

    @Autowired
    CustomerGroupCashierDeskRepository customerGroupCashierDeskRepository;

    private String ipAddress;

    public MenJinSocketService(){
        this.ipAddress = System.getenv().get("ipAddress");
    }


    public JSONObject createPersonFace(Integer shopId,
                                       Integer deskId,
                                       List<Integer> customerIdList,
                                       Integer type) {
        Long s = System.currentTimeMillis();
        logger.info("F1Start" + s);
        MenjinSocketCustomerLog customerLog;
        String faceMenjinUrl;
        String deskName = deskService.getDeskName(deskId);
        JSONObject sendParam = new JSONObject();
        JSONArray params = new JSONArray();
        MenjinSocketLog log = saveMenJinSocketLog(shopId, deskId, "savePersons");
        sendParam.put("id", log.getId());
        sendParam.put("method", "personnelData.savePersons");
        for (Integer customerId : customerIdList) {
            JSONObject person = new JSONObject();
            String code = shopId + "_" + customerId;
            Customer customer = customerService.findByCustomerId(customerId);
            List<Face> faceList = faceMapper.getFace(code);
            if (null != faceList && faceList.size() > 0) {
                List<String> urlList = new ArrayList<>();
                Face face = faceList.get(0);
                if (face.getFaceMenjinUrl() == null) {
                    faceMenjinUrl = getFaceImgBase64(face.getFaceurl(), shopId,type);
                } else {
                    faceMenjinUrl = face.getFaceMenjinUrl();
                }
                face.setFaceMenjinUrl(faceMenjinUrl);
                faceRepository.update(face);
                urlList.add(faceMenjinUrl);
                //urlList.add(face.getFaceurl());
                //String base64Img = ImgHelper.imgBase64(face.getFaceurl());
                //urlList.add(base64Img.replace("\r|\n",""));
                person.put("Type", 1);
                person.put("Code", code);
                person.put("GroupName", "默认权限组");
                person.put("Name", customer.getName());
                if (customer.getGender().equals(2)) {
                    person.put("Sex", "female");
                } else {
                    person.put("Sex", "male");
                }
                person.put("Birthday", "1980-01-01");
                person.put("URL", urlList);
                Condition condition = new Condition(MenjinSocketCustomerLog.class);
                condition.or().andEqualTo("customerId",customerId)
                        .andEqualTo("deskId",deskId);
                List<MenjinSocketCustomerLog> logList = menjinSocketCustomerLogRepository.findByCondition(condition);
                if (null == logList || logList.size() == 0){
                    customerLog = new MenjinSocketCustomerLog();
                    customerLog.setCustomerId(customerId);
                    customerLog.setCustomerName(customer.getName());
                    customerLog.setCustomerPhone(customer.getPhone());
                    customerLog.setDeskId(deskId);
                    customerLog.setShopId(shopId);
                    customerLog.setDeskName(deskName);
                    customerLog.setLatelyFaceUrl(faceMenjinUrl);
                    customerLog.setLatelyFaceUrlTime(new Date());
                    customerLog.setLatelyFaceStatus(0);
                    menjinSocketCustomerLogRepository.save(customerLog);
                }else {
                    customerLog = logList.get(0);
                    customerLog.setLatelyFaceUrl(faceMenjinUrl);
                    customerLog.setLatelyFaceUrlTime(new Date());
                    customerLog.setLatelyFaceStatus(0);
                    menjinSocketCustomerLogRepository.update(customerLog);
                }
                JSONObject personObject = new JSONObject();
                personObject.put("Person", person);
                params.add(personObject);
            }
        }
        if(params.size() == 0){
            return null;
        }
        sendParam.put("params", params);
        System.out.println(sendParam.toJSONString());
        logger.info("发送信息给" + deskId + "号门禁\n" + "发送内容:" + sendParam.toJSONString());
        logger.info("" + (System.currentTimeMillis() - s));
        logger.info("F1End" + System.currentTimeMillis());
        sendParam.put("deskId",deskId);
        return sendParam;
    }

    public List<Integer> createGroupFace(Integer shopId,
                                         Integer groupId){
        List<Integer> customerIdList = new ArrayList<>();
        Condition condition = new Condition(CustomerExtend.class);
        condition.or().andEqualTo("isAudit",1)
                .andEqualTo("shopId",shopId)
                .andEqualTo("groupId",groupId);
        List<CustomerExtend> extendList = customerExtendRepository.findByCondition(condition);
        if (null != extendList && extendList.size() > 0) {
            for (CustomerExtend extend : extendList) {
                customerIdList.add(extend.getCustomerId());
            }
            return customerIdList;
        }else {
            return null;
        }
    }

    public List<Integer> createBindingFace(Integer shopId,
                                           Integer deskId){
        CashierDesk desk = cashierDeskRepository.findById(deskId);
        String ccode = desk.getCcode();
        Condition bindingCondition = new Condition(MenjinBinding.class);
        bindingCondition.or().andEqualTo("ccode",ccode);
        MenjinBinding menjinBinding = menjinBindingRepository.findByCondition(bindingCondition).get(0);
        if (socketService.changeBindingDesk("bingDing" + menjinBinding.getId(),deskId.toString())) {

            List<Integer> groupIdList = new ArrayList<>();
            Condition extendCondition = new Condition(CustomerExtend.class);
            extendCondition.or().andEqualTo("isAudit", 1)
                    .andEqualTo("shopId", shopId);
            List<CustomerExtend> extendList = customerExtendRepository.findByCondition(extendCondition);
            if (null != extendList && extendList.size() > 0) {
                for (CustomerExtend extend : extendList) {
                    groupIdList.add(extend.getCustomerId());
                }
                return groupIdList;
            } else {
                return null;
            }
        }else {
            return null;
        }
    }


    public List<Integer> createAllDeskFace(Integer shopId) {
        List<Integer> deskIdList = cashierDeskMapper.getKuangShiMenJinDeskIdList(shopId);
        if (null != deskIdList && deskIdList.size() > 0) {
            return deskIdList;
        }else {
            return null;
        }
    }

    public MenjinSocketLog saveMenJinSocketLog(Integer shopId,
                                               Integer customerId,
                                               String method) {

        MenjinSocketLog socketLog = new MenjinSocketLog();
        socketLog.setDeskId(customerId);
        socketLog.setShopId(shopId);
        socketLog.setMethod(method);
        socketLog.setStatus(0);
        socketLog.setErrorCode("1001");
        socketLog.setCreateTime(new Date());
        menjinSocketLogRepository.save(socketLog);
        return socketLog;
    }

    public JSONObject sendDeleteFace(Integer shopId,
                                     Integer deskId,
                                     List<Integer> customerIdList) {
        JSONObject sendParam = new JSONObject();
        JSONArray params = new JSONArray();
        MenjinSocketLog log = saveMenJinSocketLog(shopId, deskId, "removePersons");
        sendParam.put("id", log.getId());
        sendParam.put("method", "personnelData.removePersons");
        for (Integer customerId : customerIdList) {
            String code = shopId + "_" + customerId;
            JSONObject codeJson = new JSONObject();
            codeJson.put("Code", code);
            params.add(codeJson);
        }
        sendParam.put("params", params);
        System.out.println(sendParam.toJSONString());
        logger.info("发送信息给" + deskId + "号门禁\n" + "发送内容:" + sendParam.toJSONString());
        sendParam.put("deskId",deskId);
        return sendParam;
        /*JSONObject result = socketService.sendtoUser(sendParam.toJSONString(), deskId.toString());
        String sendResultCode = result.getString("code");
        if (!sendResultCode.equals("0")) {
            log.setErrorCode(sendResultCode);
            menjinSocketLogRepository.update(log);
        }*/
    }

    public JSONObject deleteGroupFace(Integer shopId,
                                Integer deskId,
                                Integer groupId){
        List<Integer> customerIdList = new ArrayList<>();
        Condition condition = new Condition(CustomerExtend.class);
        condition.or().andEqualTo("isAudit",1)
                .andEqualTo("shopId",shopId)
                .andEqualTo("groupId",groupId);
        List<CustomerExtend> extendList = customerExtendRepository.findByCondition(condition);

        if (null != extendList && extendList.size() > 0) {
            for (CustomerExtend extend : extendList) {
                customerIdList.add(extend.getCustomerId());
            }
            return sendDeleteFace(shopId, deskId, customerIdList);
        }else {
            return null;
        }
    }


    public void createMenJinOrder(JSONObject param,
                                  String faceBase64) {
        logger.info("机器反馈:"+param.toJSONString());
        JSONArray array = param.getJSONArray("Events");
        JSONObject orderResult = array.getJSONObject(0);
        String code = orderResult.getString("Code");
        String facePass = "EventFaceRecognizeCutout";
        if (code.equals(facePass)) {
            JSONObject accessInfo = orderResult.getJSONObject("AccessInfo");
            Integer passResult = accessInfo.getInteger("PassResult");
            ShopMenjinOrder shopMenjinOrder = new ShopMenjinOrder();
            JSONObject commInfo = orderResult.getJSONObject("CommInfo");
            String serialNo = commInfo.getString("SerialNo");
            List<DeskExtendVO> extendVOList = cashierDeskMapper.getType(serialNo);
            if (null == extendVOList || extendVOList.size() == 0) {
                logger.error("该机器未在系统内注册或非门禁机器,SN码为:" + serialNo);
            } else {
                DeskExtendVO deskExtendVO = extendVOList.get(0);
                Integer shopId = deskExtendVO.getShopId();
                shopMenjinOrder.setShopid(shopId);
                JSONArray recognizeResults = orderResult.getJSONArray("RecognizeResults");
                JSONObject recognizeResult = recognizeResults.getJSONObject(0);
                Integer mouthocc = recognizeResult.getInteger("Mouthocc");
                shopMenjinOrder.setIsMouthocc(mouthocc);
                JSONObject object = orderResult.getJSONObject("Object");
                Double temperature = object.getDouble("Temperature");
                temperature = new BigDecimal(temperature).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
                shopMenjinOrder.setTemperature(temperature);
                String imgUrl = saveFaceImg(faceBase64, shopId);
                Integer pass = orderResult.getInteger("Pass");
                if (pass.equals(1)){
                    JSONObject personInfo = recognizeResult.getJSONObject("PersonInfo");
                    String id = personInfo.getString("ID");
                    Integer customerId = Integer.parseInt(id.split("_")[1].trim());
                    shopMenjinOrder.setCustomerid(customerId);
                }
                shopMenjinOrder.setPicUrl(imgUrl);
                shopMenjinOrder.setStatus(passResult);
                shopMenjinOrder.setDate(new Date());
                if (passResult.equals(1)) {
                    shopMenjinOrder.setStatusMsg("通行成功");
                    Integer type = deskExtendVO.getType();
                    if (type.equals(11)){
                        shopMenjinOrder.setType(1);
                    }else {
                        shopMenjinOrder.setType(2);
                    }
                } else if (passResult.equals(2)){
                    shopMenjinOrder.setStatusMsg("访客时段不符");
                } else if (passResult.equals(3)){
                    shopMenjinOrder.setStatusMsg("未配置权限组");
                } else if (passResult.equals(4)){
                    shopMenjinOrder.setStatusMsg("未配置时段");
                } else if (passResult.equals(9)){
                    shopMenjinOrder.setStatusMsg("黑名单");
                } else if (passResult.equals(14)){
                    shopMenjinOrder.setStatusMsg("门处常开状态");
                } else if (passResult.equals(15)){
                    shopMenjinOrder.setStatusMsg("门处常闭状态");
                } else if (passResult.equals(16)){
                    shopMenjinOrder.setStatusMsg("陌生人");
                } else if (passResult.equals(20)){
                    shopMenjinOrder.setStatusMsg("体温异常");
                } else if (passResult.equals(22)){
                    shopMenjinOrder.setStatusMsg("未佩戴口罩");
                } else{
                    shopMenjinOrder.setStatusMsg("未知错误");
                }
                shopMenjinOrderRepository.save(shopMenjinOrder);
            }
        }
    }

    public void getMessageFormDesk(JSONObject deskResult) {
        Integer id = deskResult.getInteger("id");
        MenjinSocketLog log = menjinSocketLogRepository.findById(id);
        log.setStatus(1);
        Integer deskId = log.getDeskId();
        String errorCode = "1";
        StringBuffer errorMsg = new StringBuffer();
        String method = deskResult.getString("method");
        if (method.equals("personnelData.removePersons")) {
            List<String> failCodeList = new ArrayList<>();
            JSONArray params = deskResult.getJSONArray("params");
            for (int i = 0; i < params.size(); i++) {
                JSONObject codeObject = params.getJSONObject(i);
                Boolean result = codeObject.getBoolean("Result");
                String code = codeObject.getString("Code");
                Integer customerId = Integer.parseInt(code.split("_")[1]);
                if (!result) {
                    errorCode = "1001";
                    failCodeList.add(code);
                }else {
                    Condition condition = new Condition(MenjinSocketCustomerLog.class);
                    condition.or().andEqualTo("customerId",customerId)
                            .andEqualTo("deskId",deskId);
                    MenjinSocketCustomerLog customerLog = menjinSocketCustomerLogRepository.findByCondition(condition).get(0);
                    customerLog.setDeleted(1);
                    customerLog.setDeleteTime(new Date());
                    menjinSocketCustomerLogRepository.update(customerLog);
                }
            }
            if (failCodeList.size() > 0) {
                for (String failCode : failCodeList) {
                    errorMsg.append(failCode).append("删除人脸操作失败");
                }
                log.setErrorCode(errorCode);
                log.setErrorMsg(errorMsg.toString());
            } else {
                log.setErrorCode("0");
                log.setErrorMsg("");
            }
            menjinSocketLogRepository.update(log);
        } else if (method.equals("personnelData.savePersons")) {
            JSONArray params = deskResult.getJSONArray("params");
            for (int i = 0; i < params.size(); i++) {
                JSONObject codeObject = params.getJSONObject(i);
                Boolean result = codeObject.getBoolean("Result");
                String code = codeObject.getString("Code");
                Integer customerId = Integer.parseInt(code.split("_")[1]);
                if (!result) {
                    Integer faceErrorCode = codeObject.getInteger("ErrorCode");
                    if (faceErrorCode.equals(589840)){
                        errorMsg.append(code + "下发人员人脸跟底库一致");
                    }else {
                        errorMsg.append(code + "人员注册失败");
                    }
                } else {
                    JSONArray errorCodePic = codeObject.getJSONArray("ErrorCodePic");
                    Integer faceCode = errorCodePic.getInteger(0);
                    if (faceCode != 0 && faceCode != 1) {
                        errorMsg.append(code + "人脸创建失败,请选择清晰正确图片");
                    }else {
                        Condition condition = new Condition(MenjinSocketCustomerLog.class);
                        condition.or().andEqualTo("customerId",customerId)
                                .andEqualTo("deskId",deskId);
                        MenjinSocketCustomerLog customerLog = menjinSocketCustomerLogRepository.findByCondition(condition).get(0);
                        customerLog.setLatelyFaceStatus(1);
                        customerLog.setDeskFaceUrl(customerLog.getLatelyFaceUrl());
                        customerLog.setDeskFaceUrlTime(new Date());
                        customerLog.setDeleted(0);
                        menjinSocketCustomerLogRepository.update(customerLog);
                    }
                }
            }
            if (errorMsg.length() > 0) {
                log.setErrorCode("2001");
                log.setErrorMsg(errorMsg.toString());
            } else {
                log.setErrorCode("0");
                log.setErrorMsg("");
            }
            menjinSocketLogRepository.update(log);
        }
    }

    public String getFaceImgBase64(String url,
                                   Integer shopId,
                                   Integer type) {
        String uuid = UUID.randomUUID().toString();
        StringBuffer outputFilepathStringBuffer;
        if (type.equals(1)) {
            outputFilepathStringBuffer = new StringBuffer("/usr/local/nginx/html/pad/sendFace/")
                    .append(shopId);
            File dirOutput = new File(outputFilepathStringBuffer.toString());
            if (!dirOutput.exists()) {
                dirOutput.mkdir();
            }
        }else {
            outputFilepathStringBuffer = new StringBuffer("/data/html/pad");
            File dirOutput = new File(outputFilepathStringBuffer.toString());
            if (!dirOutput.exists()) {
                dirOutput.mkdir();
            }
            outputFilepathStringBuffer.append("/sendFace");
            dirOutput = new File(outputFilepathStringBuffer.toString());
            if (!dirOutput.exists()) {
                dirOutput.mkdir();
            }
            outputFilepathStringBuffer.append("/"+shopId);
            if (!dirOutput.exists()) {
                dirOutput.mkdir();
            }
        }

        /*StringBuffer outputFilepathStringBuffer = new StringBuffer("/Library/Tomcat/webapps/ROOT/")
                .append(shopId);*/


        String newFileName = outputFilepathStringBuffer.append("/").append(uuid).append(".png").toString();

        String httpFileName = new StringBuffer("http://")
                .append(ipAddress)
                .append(":8019/pad/sendFace/")
                .append(shopId).append("/").append(uuid).append(".jpg").toString();

        /*String httpFileName = new StringBuffer("http://")
                .append("192.168.10.136")
                .append(":8080/")
                .append(shopId).append("/").append(uuid).append(".jpg").toString();*/

        String base64ImgStr = ImgHelper.imgBase64(url);

        ImageBase64Util.base64StringToImage(base64ImgStr, newFileName);

        try {
            BufferedImage bufferedImage = ImageIO.read(new File(newFileName));
            // create a blank, RGB, same width and height, and a white
            // background
            BufferedImage newBufferedImage = new BufferedImage(
                    bufferedImage.getWidth(), bufferedImage.getHeight(),
                    BufferedImage.TYPE_INT_RGB);
            // TYPE_INT_RGB:创建一个RBG图像，24位深度，成功将32位图转化成24位
            newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0,
                    Color.WHITE, null);
            // write to jpeg file
            String newJpgName = newFileName.substring(0, newFileName.length() - 4) + ".jpg";
            ImageIO.write(newBufferedImage, "jpg", new File(newJpgName));
            byte[] bytes = FileUtils.readFileToByteArray(new File(newJpgName));
            // 图片小于500kb
            bytes = ImageBase64Util.compressPicForScale(bytes, 500, "x");
            FileUtils.writeByteArrayToFile(new File(newJpgName), bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return httpFileName;
    }

    public String saveFaceImg(String faceBase64,
                              Integer shopId) {
        String uuid = UUID.randomUUID().toString();

        StringBuffer outputFilepathStringBuffer = new StringBuffer("/usr/local/nginx/html/pad/menJinFace/")
                .append(shopId);

        /*StringBuffer outputFilepathStringBuffer = new StringBuffer("/Library/Tomcat/webapps/ROOT/")
                .append(shopId);*/

        File dirOutput = new File(outputFilepathStringBuffer.toString());
        if (!dirOutput.exists()) {
            dirOutput.mkdir();
        }
        String newFileName = outputFilepathStringBuffer.append("/").append(uuid).append(".png").toString();

        String httpFileName = new StringBuffer("http://")
                .append(ipAddress)
                .append(":8019/pad/menJinFace/")
                .append(shopId).append("/").append(uuid).append(".png").toString();


        /*String httpFileName = new StringBuffer("http://")
                .append("192.168.10.136")
                .append(":8080/")
                .append(shopId).append("/").append(uuid).append(".png").toString();*/

        ImageBase64Util.base64StringToImage(faceBase64, newFileName);

        return httpFileName;
    }


    public boolean isCustomerGroup(Integer deskId,
                                   Integer customerId,
                                   Integer shopId){

        Condition condition = new Condition(CustomerGroupCashierDesk.class);
        condition.or().andEqualTo("cashierDeskId",deskId);
        List<CustomerGroupCashierDesk> deskList = customerGroupCashierDeskRepository.findByCondition(condition);

        if (null == deskList || deskList.size() == 0){
            return true;
        }else {
            Condition extendCondition = new Condition(CustomerExtend.class);
            extendCondition.or().andEqualTo("customerId",customerId)
                    .andEqualTo("shopId",shopId)
                    .andEqualTo("isAudit",1);
            List<CustomerExtend> extendList = customerExtendRepository.findByCondition(extendCondition);
            if (null == extendList || extendList.size() == 0){
                return false;
            }else {
                CustomerExtend customerExtend = extendList.get(0);
                for (CustomerGroupCashierDesk desk : deskList) {
                    if (desk.getCustomerGroupId().equals(customerExtend.getGroupId())) {
                        return true;
                    }
                }
            }
            return false;
        }

    }

    public void sendParam(JSONObject sendParam,
                          String serialNo){
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE));
        headers.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));
        sendParam.put("SerialNo",serialNo);
        String message = sendParam.toJSONString();
        logger.info(message);
        HttpEntity<String> entity = new HttpEntity<String>(message, headers);
        ResponseEntity<String> resp = restTemplate.postForEntity("http://172.17.0.24:8081/acDevice/sendMsg", entity, String.class);
//      ResponseEntity<String> resp = restTemplate.postForEntity("http://123.206.224.209/api/zzg/hyCodePay", entity, String.class);
        String respBody = resp.getBody();
        logger.info(respBody);

    }
}
